#pragma once
#include <iostream>
#include <new>
#include <mutex> 
//定长内存池
template <typename T>
class ObjectPool{
    public:
        //申请空间
        T* New()
        {
            T* obj = nullptr;
            if(_freelist)
            {
                //把释放掉的内存给利用起来
                void* next = *(void**)_freelist;
                obj = (T*)_freelist;
                _freelist = next;
            }else{
                //需要我们去申请内存
                if(_recommondBytes < sizeof(T))
                {
                    _recommondBytes = 128*1024;
                    _memory = (char*)malloc(_recommondBytes);
                    if(_memory==nullptr)
                    {
                        throw std::bad_alloc();
                    }
                }
                obj = (T*)_memory;
                //判断T类型大小是否是小于一个指针大小的
                size_t objsize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
                _memory +=  objsize;
                _recommondBytes -= objsize;
            }
            //定位new，初始化obj
            new(obj)T;
            return obj;
        }
        //释放空间
        void Delete(T* obj)
        {
            //把资源清理干净
            obj->~T();
            //头插
            *(void**)obj = _freelist;
            _freelist = obj;
        }
    public:
        std::mutex _Objmutex;
    private:
        char* _memory = nullptr;
        //判断是否要继续申请一个定长的内存
        size_t _recommondBytes = 0;
        //用来管理回收释放掉的空间
        void* _freelist = nullptr;
};